/*!
 * gulp
 * $ npm install gulp gulp-util gulp-jade glob webpack gulp-cond gulp-sequence gulp-autoprefixer gulp-less gulp-minify-css  gulp-rev gulp-rev-replace  gulp-imagemin  gulp-cache del  --save-dev
 * 使用淘宝镜像 --registry=https://registry.npm.taobao.org --verbose
 */
// Load plugins
var gulp = require('gulp')
//css
    , autoprefixer = require('gulp-autoprefixer')
    , minifycss = require('gulp-minify-css')
    , less = null
//jade
    , jade = null
//js
    , uglify = require('gulp-uglify')
//webpack
    , webpack = null
    , glob = null
//images
    , imagemin = null
    , cache = null
//css sprites
    , cssSprites = null
//html
    , htmlmin = null
//md5 hash
    , rev = require('gulp-rev')
    , revReplace = require('gulp-rev-replace')
//replace
    , stringReplace = require('gulp-replace')
//util
    , del = require('del')
    , fs = require("fs")
    , path = require("path")
    , gulpSequence = require('gulp-sequence')
    , gutil = require("gulp-util")
    , cond = require('gulp-cond')
    , log = false
    , isDev = true //是否生产环境
    ;



var BuildConfig = {
    'origin': 'src/',                         //开发环境目录
    'output': 'build/',                       //生产环境目录
    'css_path': "css/",                     //生产环境css目录
    'img_path': "images/",                     //生产环境image目录
    'js_path': "js/lib/",                      //lib js
    'modules_js_path': "js/modules/",          //modules js
    'webpack_entry': "js/job/",               //webpack入口目录
    'jade_path': "page/firstpage/",          //生产环境jade目录
    'jade_template_path': "page/fragpage/",  //生产环境jade目录
    'sprites_icon_path': "images/sprites/",  //需要cssSprites所需图片路径

    'watch_js_path':"js/",                   //wathch js路径
    'view_src_path':"page/",                //模板路径
    'html_path':"",                           //html文件路径
    'webpack_config_path':"./webpack.config.js", //webpack.config.js文件路径
    'need_copy_path': [                       //需要复制的文件或文件夹
        'fonts/',
        'api/'
    ],
    'need_jade_build': true,                 //是否需要jade编译
    'need_jade_template_build': true,        //是否需要jade模版编译
    'need_webpack_build': true,              //是否需要webpack编译
    'need_styles_translate': true,           //是否需要less编译
    'need_css_sprites': true                //是否需要cssSprites
};

var temp_path = "client/temp_build/"; //临时文件目录

var origin_css_path = BuildConfig.origin + BuildConfig.css_path,
    origin_img_path = BuildConfig.origin + BuildConfig.img_path,
    origin_js_path = BuildConfig.origin + BuildConfig.js_path,
    origin_modules_js_path = BuildConfig.origin + BuildConfig.modules_js_path,
    origin_watch_js_path = BuildConfig.origin + BuildConfig.watch_js_path,
    origin_webpack_entry = BuildConfig.origin + BuildConfig.webpack_entry,
    origin_jade_path = BuildConfig.origin + BuildConfig.jade_path,
    origin_jade_template_path = BuildConfig.origin + BuildConfig.jade_template_path,
    origin_view_src_path = BuildConfig.origin + BuildConfig.view_src_path,
    origin_sprites_icon_path = BuildConfig.origin + BuildConfig.sprites_icon_path,
    temp_css_path = temp_path + BuildConfig.css_path,
    temp_img_path = temp_path + BuildConfig.img_path,
    temp_js_path = temp_path + BuildConfig.js_path,
    temp_modules_js_path = temp_path + BuildConfig.modules_js_path,
    temp_webpack_entry = temp_path + BuildConfig.webpack_entry,
    temp_jade_path = temp_path + BuildConfig.jade_path,
    temp_jade_template_path = temp_path + BuildConfig.jade_template_path,
    temp_view_src_path = temp_path + BuildConfig.view_src_path,
    temp_sprites_icon_path = temp_path + BuildConfig.sprites_icon_path,
    dest_css_path = BuildConfig.output + BuildConfig.css_path,
    dest_img_path = BuildConfig.output + BuildConfig.img_path,
    dest_js_path = BuildConfig.output + BuildConfig.js_path,
    dest_modules_js_path = BuildConfig.output + BuildConfig.modules_js_path,
    dest_webpack_entry = BuildConfig.output + BuildConfig.webpack_entry,
    dest_jade_path = BuildConfig.output + BuildConfig.jade_path,
    dest_jade_template_path = BuildConfig.output + BuildConfig.jade_template_path,
    dest_view_src_path = BuildConfig.output + BuildConfig.view_src_path,
    dest_html_path = BuildConfig.output + BuildConfig.html_path,
    dest_sprites_icon_path = BuildConfig.output + BuildConfig.sprites_icon_path;

var Log = function () {
    if (log || isDev) {
        arguments = [].slice.apply(arguments);
        arguments.forEach(function (item, index) {
            console.log(item);
        });
        console.log("\r\n");
    }
};


/*
 * 清理
 */
gulp.task('clean', function (cb) {
    //清除文件 用一个临时的文件夹temp_app/是为了静态文件的版本控制（否则dist会有两套静态文件）
    return del([BuildConfig.output, temp_path], cb);
});

/*
 * 复制文件，编译准备
 */
gulp.task('copyBefore', function (cb) {
    return gulp.src(BuildConfig.origin + "/*/**")
        .pipe(gulp.dest(temp_path))
});

/**
 * jade编译
 */
gulp.task("jade_build", function (cb) {
    jade = require("gulp-jade");
    return gulp.src(origin_jade_path + "/**/*.jade")
        .pipe(cond(isDev, jade({pretty: true}), jade()))
        .on('error', cb)
        .pipe(gulp.dest(BuildConfig.output));
});



/**
 * jade 模版编译(编译成js,同事拷贝一份jade用于node使用)
 */
gulp.task("jade_template_build", function (cb) {
    jade = require("gulp-jade");
    gulp.src(origin_jade_template_path + "/**/*.jade")
        .pipe(gulp.dest(dest_jade_template_path))

    return gulp.src(origin_jade_template_path + "/**/*.jade")
        .pipe(cond(isDev, jade({client: true}), jade({client: true, pretty: true})))
        .on('error', cb)
        .pipe(gulp.dest(cond(isDev, dest_jade_template_path, temp_jade_template_path)));
});

/**
 * webpack打包编译
 */
gulp.task("webpack_build", function (callback) {
    glob = require("glob");
    webpack = require("webpack");

    function getEntry() {
        var entry = {};
        glob.sync(origin_webpack_entry + "*.js").forEach(function (name) {
            var tempName = name.match(/([^/]+?)\.(coffee|js)$/)[1];
            entry[tempName] = "./" + origin_webpack_entry + tempName;
        });
        return entry;
    }

    var webpackConfig = require(BuildConfig.webpack_config_path);
    var _Config = Object.create(webpackConfig);
    /* if (process.env.NODE_ENV == "production") {
     jsConfig.plugins.push(new webpack.optimize.UglifyJsPlugin());
     }*/
    _Config.entry = getEntry();
    _Config.output.path = (isDev ? dest_webpack_entry : temp_webpack_entry);
    if (!isDev) {
        _Config.plugins.push(new webpack.optimize.UglifyJsPlugin())
    }
    // _Config.output.publicPath = ;
    webpack(_Config, function (err, stats) {
        if (err) {
            return console.log(err);
        }
        if (log || isDev) {
            gutil.log("build-js", stats.toString({
                colors: true
            }));
        }
        callback();
    });

});



/*
 * less 预处理编译
 */
gulp.task('styles_translate', function (cb) {
    less = require('gulp-less');
    return gulp.src(temp_css_path + '/*.less')
        .pipe(less())
        .on('error', cb)
        .pipe(gulp.dest(cond(isDev, dest_css_path, temp_css_path)));
});

/*
 * autoprefixer 浏览器前缀自动填写
 * minifycss 压缩、合并css
 */
gulp.task('styles_minify', function () {
    return gulp.src(temp_css_path + '/**/*.css')
        .pipe(autoprefixer('last 8 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
        .pipe(cond(!isDev, minifycss()))
        .pipe(gulp.dest(cond(isDev, dest_css_path, temp_css_path)));
});

gulp.task('css_sprites', function (cb){
    cssSprites = require('gulp.spritesmith');
    var imgName = 'sprites.png',
        // retinaImgName = 'sprites@2x.png',
        cssName = 'sprites.css',
        error = false;
    var spriteData = gulp.src(origin_sprites_icon_path+"/*").pipe(
            cssSprites({
                // retinaSrcFilter: [origin_sprites_icon_path+"/*@2x.*"],
                // retinaImgName: retinaImgName,
                imgName: imgName,
                cssName: cssName
            })
        ).on("error", function(){
            error = true;
            cb&&cb();
        })
    if(error){
        return false;
    }
    var target_css_path = cond(isDev, dest_css_path, temp_css_path),
        target_img_path = cond(isDev, dest_img_path, temp_img_path);

    spriteData.img.pipe(gulp.dest(target_img_path));

    return spriteData.css
           .pipe(stringReplace(new RegExp(imgName, "mg"), "../images/"+imgName))
           // .pipe(stringReplace(new RegExp(retinaImgName, "mg"), "../images/"+retinaImgName))
           .pipe(gulp.dest(target_css_path));

})

/*
 * 压缩图片
 * https://www.npmjs.com/package/gulp-imagemin-quiet/
 * optimizationLevel png压缩等级0~7
 * progressive jpg是否无损压缩
 * interlaced gif
 */
gulp.task('images_minify', function (callback) {
    imagemin = require("gulp-imagemin");
    cache = require("gulp-cache");
    return gulp.src(origin_img_path + '/**/*')
        //.pipe(cond(!isDev, cache(imagemin({
        //    optimizationLevel: 3,
        //    progressive: false,
        //    interlaced: true
        //}))))
        // .pipe(gulp.dest(temp_img_path));
        .pipe(gulp.dest(cond(isDev, dest_img_path, temp_img_path)));

});


/*
 * 生成jade_template md5指纹、映射文件manifest
 */
gulp.task("jade_template_reversion", function () {
    return gulp.src(temp_jade_template_path + "/**/*.js")
        // .pipe(rev()) // Rename the concatenated files
        // .pipe(gulp.dest(dest_jade_template_path))
        // .pipe(rev.manifest())
        .pipe(gulp.dest(dest_jade_template_path));

});


/*
 * 生成js md5指纹、映射文件manifest
 * 需要将template的md5文件更新到/job下
 */
gulp.task("jade_js_reversion", function () {
    //将js生成版本控制文件名 如main-f056a2d49b.js 同时生成manifest map文件

    //取jade_template manifest文件
    var manifest_template = gulp.src(dest_jade_template_path + "rev-manifest.json");

    return gulp.src([temp_webpack_entry + "*.js"])
        .pipe(revReplace({manifest: manifest_template}))
        .pipe(gulp.dest(temp_webpack_entry))
        .pipe(rev()) // Rename the concatenated files
        .pipe(gulp.dest(dest_webpack_entry))
        .pipe(rev.manifest())
        .pipe(gulp.dest(dest_webpack_entry));
});

/*
 * 生成js md5指纹、映射文件manifest
 * 需要将template的md5文件更新到/job下
 */
gulp.task("other_js_handle", function () {
    //将js生成版本控制文件名 如main-f056a2d49b.js 同时生成manifest map文件

    //取jade_template manifest文件
    gulp.src([temp_modules_js_path + "/**/*"])
        .pipe(gulp.dest(dest_modules_js_path))

    return gulp.src([temp_js_path + "/**/*.js"])
        .pipe(cond(!isDev, rev())) // Rename the concatenated files
        .pipe(gulp.dest(dest_js_path))
        .pipe(cond(!isDev,rev.manifest()))
        .pipe(cond(!isDev,gulp.dest(dest_js_path)));
});



/*
 * 生成图片 md5指纹、映射文件manifest
 */
gulp.task("images_reversion", function () {
    return gulp.src([temp_img_path + "**/*"])
        .pipe(rev()) // Rename the concatenated files
        .pipe(gulp.dest(dest_img_path))
        .pipe(rev.manifest())
        .pipe(gulp.dest(dest_img_path));
});

/*
 * 生成css md5指纹、映射文件manifest
 * css指纹生成比较特殊，需要先将指纹图片替换
 */
gulp.task("styles_reversion", function () {

    //取图片manifest文件
    var manifest_img = gulp.src(dest_img_path + "rev-manifest.json");

    //先将文件中的图片文件名替换
    return gulp.src(temp_css_path + "/**/*.css")
        .pipe(revReplace({manifest: manifest_img}))
        .pipe(gulp.dest(temp_css_path))
        .pipe(rev())
        .pipe(gulp.dest(dest_css_path))
        .pipe(rev.manifest())
        .pipe(gulp.dest(dest_css_path))

});




/*
 * 替换HTML中js、css、图片指纹文件
 * https://github.com/jamesknelson/gulp-rev-replace
 * replaceInExtensions 支持的文件类型 Default: ['.js', '.css', '.html', '.hbs']
 */
gulp.task("html_revreplace", function(){
    var manifest_css = gulp.src(dest_css_path + "rev-manifest.json");
    var manifest_jade_js = gulp.src(dest_webpack_entry + "rev-manifest.json");
    var manifest_other_js = gulp.src(dest_js_path + "rev-manifest.json");
    var manifest_img = gulp.src(dest_img_path + "rev-manifest.json");

    /** html 文件 html文件由jade编译**/
    return gulp.src([dest_html_path + "/**/*.html"])
        .pipe(revReplace({manifest: manifest_jade_js}))
        .pipe(revReplace({manifest: manifest_other_js}))
        .pipe(revReplace({manifest: manifest_css}))
        .pipe(revReplace({manifest: manifest_img}))
        .pipe(gulp.dest(dest_html_path));

})

/*
 * 替换HTML中js、css、图片指纹文件
 */
gulp.task("copy_view", function () {
    return gulp.src([origin_view_src_path + "/alertlayer/**/*"])
        .pipe(gulp.dest(dest_view_src_path+"/alertlayer/"));

});

/*
 * 复制其他文件
 */
gulp.task("copyAfter", function (cb) {
    if (BuildConfig.need_copy_path && BuildConfig.need_copy_path.length) {
        BuildConfig.need_copy_path.forEach(function (item, index) {
            fs.stat(BuildConfig.origin + item, function (err, stat) {
                if (!err) {
                    var origin_path = null,
                        output_path = null;
                    if (stat.isDirectory()) {
                        origin_path = BuildConfig.origin + item + "/**";
                        output_path = BuildConfig.output + item;
                    } else if (stat.isFile()) {
                        origin_path = BuildConfig.origin + item;
                        output_path = path.dirname(BuildConfig.output + item); //获取文件所在目录
                    }
                    gulp.src(origin_path).pipe(gulp.dest(output_path));
                }
            })
        });
        cb();
    } else {
        cb();
    }
});
/*
 * 清除临时目录
 */
gulp.task("cleanTemp", function (cb) {
    return del(temp_path);
});


/*
 * gulp-sequence 按顺序执行任务
 *  https://www.npmjs.com/package/gulp-sequence/
 */

function generate_config_task(callback) {
    var task_func_str = `gulpSequence(
        'clean',
        'copyBefore',
        ['jade_build','jade_template_build','webpack_build'],
        ['styles_translate','css_sprites'],
        ['styles_minify', 'images_minify', 'jade_template_reversion', 'other_js_handle'],
        ['jade_js_reversion', 'images_reversion'],
        'styles_reversion',
        'html_revreplace',
        'copyAfter',
        'cleanTemp'
      )(callback)`;

    if (!BuildConfig.need_jade_build) {
        task_func_str = task_func_str.replace(/(\s*(['"])jade_build\2\s*,)|(,\s*(['"])jade_build\4\s*(\]))/mg, '$5');
    }
    if (!BuildConfig.need_styles_translate) {
        task_func_str = task_func_str.replace(/(\s*(['"])styles_translate\2\s*,)|(,\s*(['"])styles_translate\4\s*(\]))/mg, '$5');
    }
    if (!BuildConfig.need_webpack_build) {
        task_func_str = task_func_str.replace(/(\s*(['"])webpack_build\2\s*,)|(,\s*(['"])webpack_build\4\s*(\]))/mg, '$5');
    }
    if (!BuildConfig.need_css_sprites) {
        task_func_str = task_func_str.replace(/(\s*(['"])css_sprites\2\s*,)|(,\s*(['"])css_sprites\4\s*(\]))/mg, '$5');
    }
    Log(task_func_str);
    return task_func_str;
}


/**
 * 用于dev watch配置
 * @return {[type]} [description]
 */
function generate_dev_config_task() {
    var task_func_str = `gulpSequence(
        'clean',
        'copyBefore',
        'css_sprites',
        ['jade_build', 'jade_template_build', 'webpack_build', 'styles_minify', 'images_minify', 'other_js_handle'],
        'styles_translate',
        'copyAfter',
        'cleanTemp',
        'watch'
      )(callback)`;
    if (!BuildConfig.need_jade_build) {
        task_func_str = task_func_str.replace(/(\s*(['"])jade_build\2\s*,)|(,\s*(['"])jade_build\4\s*(\]))/mg, '$5');
    }
    if (!BuildConfig.need_styles_translate) {
        task_func_str = task_func_str.replace(/(\s*(['"])styles_translate\2\s*,)|(,\s*(['"])styles_translate\4\s*(\]))/mg, '$5');
    }
    if (!BuildConfig.need_webpack_build) {
        task_func_str = task_func_str.replace(/(\s*(['"])webpack_build\2\s*,)|(,\s*(['"])webpack_build\4\s*(\]))/mg, '$5');
    }
    if (!BuildConfig.need_css_sprites) {
        task_func_str = task_func_str.replace(/(\s*(['"])css_sprites\2\s*,)|(,\s*(['"])css_sprites\4\s*(\]))/mg, '$5');
    }
    return task_func_str
}



gulp.task("watch", function () {
    isDev = true;
    temp_path = BuildConfig.origin;
    temp_jade_path = temp_path + "/page/";
    temp_css_path = temp_path + "/css/";
    temp_js_path = temp_path + "/js/";
    gulp.watch(`${origin_jade_path}/**/*`, ['jade_build']);
    gulp.watch(`${origin_jade_template_path}/**/*`, ['jade_template_build', 'jade_build']);
    gulp.watch(`${origin_css_path}/**/*`, ['styles_translate', 'styles_minify']);
    gulp.watch(`${origin_watch_js_path}/**/*`, ['webpack_build']);
    gulp.watch(`${origin_img_path}/**/*`, ['images_minify', 'css_sprites']);
});


gulp.task('default', function (callback) {
    //默认开发环境编译
    isDev = true;
    eval(generate_dev_config_task())
});

gulp.task('dev', function (callback) {
    //开发环境编译
    isDev = true;
    //watch状态下如果不加callback 会出现The thunk already filled错误
    eval(generate_dev_config_task())
});

gulp.task('production', function (callback) {
    //生产环境编译
    isDev = false;
    eval(generate_config_task())
});
